package main

import "fmt"

/*
*
如果发送者知道，没有更多的值需要发送到channel的话，
那么让接收者也能及时知道没有多余的值可接收将是有用的，
因为接收者可以停止不必要的接收等待。
这可以通过内置的close函数来关闭channel实现。
*/
//func main() {
//	c := make(chan string)
//	go func() {
//		for i := 0; i < 3; i++ {
//			c <- "zhang" + strconv.Itoa(i)
//		}
//		close(c)
//	}()
//
//	for {
//		// ok = true 说明channel没有关闭，为false说明管道已关闭
//		if data, ok := <-c; ok {
//			fmt.Println(data)
//		} else {
//			break
//		}
//	}
//	fmt.Println("Finished")
//}
//可以使用 range 来迭代不断操作channel：
func main() {
	//c := make(chan int)
	//
	//go func() {
	//	for i := 0; i < 5; i++ {
	//		c <- i
	//	}
	//	close(c)
	//	// c <- 1 panic: send on closed channel
	//}()
	//
	////可以使用 range 来迭代不断操作channel：
	//for data := range c {
	//	fmt.Println(data)
	//}
	//fmt.Println("Finished")
	fmt.Println("-- -- -- -- --")
	//可以将 channel 隐式转换为单向队列，只收或只发，不能将单向 channel 转换为普通 channel
	c := make(chan int)
	go counter(c)
	printer(c)
	//
}

var ch1 chan int       // ch1是一个正常的channel，是双向的
var ch2 chan<- float64 // ch2是单向channel，只用于写float64数据
var ch3 <-chan int     // ch3是单向channel，只用于读int数据

// chan<- //只写
func counter(out chan<- int) {
	defer close(out)
	for i := 0; i < 5; i++ {
		out <- i //如果对方不读 会阻塞
	}
}

// <-chan //只读
func printer(in <-chan int) {
	for num := range in {
		fmt.Println(num)
	}
}
